﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace AMSReportBuildService
{
    public class ObjXmlReader
    {
        public ObjXmlReader(string xmlPath)
        {
            m_XMLPath = xmlPath;
        }

        protected string m_XMLPath;


        public string GetNodeAttributeValue(string className, string attribulteName)
        {
            return GetNodeAttributeValue(className, attribulteName, false);
        }

        public string GetNodeAttributeValue(string className, string attribulteName, bool isIgnore)
        {
            XmlNode nd = GetClassXMLNode(className);
            return GetNodeAttributeValue(nd, attribulteName, isIgnore);
        }

        public string GetNodeAttributeValue(string className, string typeName, string attribulteName, bool isIgnore)
        {
            XmlNode nd = GetClassTypeNameXMLNode(className, typeName);
            return GetNodeAttributeValue(nd, attribulteName, isIgnore);
        }

        public string GetNodeAttributeValue(XmlNode node, string attribulteName)
        {
            return GetNodeAttributeValue(node, attribulteName, false);
        }

        public string GetNodeAttributeValue(XmlNode node, string attribulteName, bool isIgnore)
        {
            if (node.Attributes.GetNamedItem(attribulteName) == null || node.Attributes[attribulteName].Value == "")
            {
                if (isIgnore)
                    return "";
                throw new ArgumentException("配置文件有误：请设置节点属性（" + attribulteName + "），指定节点为\r\n" + node.OuterXml);
            }
            else
                return node.Attributes[attribulteName].Value;
        }


        private XmlNode ReturnSingleNode(XmlNodeList nodeList)
        {
            if (nodeList == null || nodeList.Count == 0)
                throw new ArgumentException("找不到指定类设置信息");
            else if (nodeList.Count > 1)
                throw new ArgumentException("同一个类在设置文件中多次定义");
            else
                return nodeList[0];
        }

        public XmlNode GetXmlNode(string xPath)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(m_XMLPath);
            XmlNodeList nl = doc.SelectNodes(xPath);
            if (nl == null || nl.Count == 0)
                return null;
            return nl[0];
        }

        public XmlNode GetXmlNode(string className, string typeName, string nodeName)
        {
            string xPath = "Setting/" + className;
            if (!string.IsNullOrEmpty(typeName))
                xPath += "/" + typeName;
            if (!string.IsNullOrEmpty(nodeName))
                xPath += "/" + nodeName;
            return GetXmlNode(xPath);
        }

        public XmlNode GetProXMLNode(string className, string typeName, string proName)
        {
            string xPath = "Setting/" + className;
            if (!string.IsNullOrEmpty(typeName))
                xPath += "/" + typeName;
            if (!string.IsNullOrEmpty(proName))
                xPath += "/property[@Name='" + proName + "']";
            return GetXmlNode(xPath);
        }

        public XmlNode GetProXMLNode(string className, string proName)
        {
            return GetProXMLNode(className, null, proName);
        }

        public string GetProXMLNodeAttrValue(string className, string typeName, string proName, string attrName)
        {
            XmlNode nd = GetProXMLNode(className, typeName, proName);
            if (nd != null && attrName.Length > 0)
                return GetNodeAttributeValue(nd, attrName, true);
            return "";
        }

        public XmlNodeList GetNodeList(string xPath)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(m_XMLPath);
            XmlNodeList nl = doc.SelectNodes(xPath);
            return nl;
        }

        public XmlNode GetClassXMLNode(string className)
        {

            XmlDocument doc = new XmlDocument();
            doc.Load(m_XMLPath);
            XmlNodeList nl = doc.SelectNodes("Setting/" + className);
            return ReturnSingleNode(nl);
        }

        public XmlNode GetClassTypeNameXMLNode(string className, string typeName)
        {
            string xPath = "Setting/" + className;
            if (!string.IsNullOrEmpty(typeName))
                xPath += "/" + typeName;
            var node = GetXmlNode(xPath);
            return node;
        }

        public XmlNodeList GetChildNodesFromXML(string className, string typeName, string childNodeName)
        {
            XmlNode nd;
            if (typeName == null || typeName.Length == 0)
                nd = GetClassXMLNode(className);
            else
                nd = GetClassTypeNameXMLNode(className, typeName);
            XmlNodeList nl = nd.SelectNodes(childNodeName);
            if (nl == null || nl.Count == 0)
                throw new ArgumentException("找不到相关的属性");
            return (nl);
        }

        public XmlNodeList GetChildNodesFromXML(string className, string childNodeName)
        {
            XmlNode nd = GetClassXMLNode(className);
            return GetChildNodesFromXML(nd, childNodeName, false);
        }
        public XmlNodeList GetChildNodesFromXML(string className, string childNodeName, bool isReturnNull)
        {
            XmlNode nd = GetClassXMLNode(className);
            return GetChildNodesFromXML(nd, childNodeName, isReturnNull);
        }


        public XmlNodeList GetChildNodesFromXML(XmlNode parentNode, string childNodeName)
        {
            return GetChildNodesFromXML(parentNode, childNodeName, false);
        }
        public XmlNodeList GetChildNodesFromXML(XmlNode parentNode, string childNodeName, bool isReturnNull)
        {
            XmlNodeList nl = parentNode.SelectNodes(childNodeName);
            if (nl == null || nl.Count == 0)
            {
                if (isReturnNull)
                    return null;
                else
                    throw new ArgumentException("找不到相关的属性");
            }
            return (nl);
        }

        public void ShowErrorSettingInfo(XmlNode settingNode, Exception ex)
        {
            //throw ex;
            throw new ArgumentException(ex.Message + "<br><br>分析配置节点出错,节点内容为:\"" + settingNode.OuterXml + "\"");
        }
    }
}
